package com.zmn.oms.api.listener;

import com.alibaba.fastjson.JSON;
import com.github.ltsopensource.core.domain.Job;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.manager.lts.interfaces.task.TaskManager;
import com.zmn.manager.mq.annotation.AliyunMQHandler;
import com.zmn.manager.mq.annotation.AliyunMQListener;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.manager.utils.OmsMqTagConsts;
import com.zmn.oms.manager.utils.TaskConsts;
import com.zmn.oms.model.dto.order.create.CreateOrderFailMessage;
import com.zmn.oms.zmn.facade.interfaces.order.CreateOrderFacade;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 类描述：分类信息补全导致创建订单失败
 *
 * @author lhl
 * @date 2020/01/10 18:20
 */
@Slf4j
@AliyunMQListener(topic = "${spring.mq.topic.oms}")
@Component
public class OrderCreateFailListener {

    private static final Logger logger = LoggerFactory.getLogger(OrderCreateFailListener.class);

    // 录单失败重试时的间隔时间基数
    private int timeWaitUnit;

    @Autowired
    TaskManager taskManager;

    /**
     * 创建订单失败
     *
     * @param message
     */
    @AliyunMQHandler(tags = OmsMqTagConsts.ZMN_TOPIC_OMS_ORDER_CREATE_FAIL_SYNC_API)
    public void orderNew(String message) {
        try {
            logger.info("#mq#order#createFail#recive message:{}", message);
            CreateOrderFailMessage createOrderFailMessage = JSON.parseObject(message, CreateOrderFailMessage.class);
            CreateOrderFacade createOrderFacade
                    = OrderChangeNotifyFactory.getOrderCreateFailNotifyInstance(createOrderFailMessage);

            ResultDTO resultDTO = createOrderFacade.onCreateOrderFail(createOrderFailMessage);

            // 处理失败，尝试再次处理
            if (resultDTO.isStatusBool() == false) {
                // 获取之前处理过的次数
                int procTimes = createOrderFailMessage.getProcessTimes();

                // 已尝试三次，且依旧处理失败的，记录信息，放弃再次尝试
                if (procTimes >= 3) {
                    log.info("多次处理<创建订单失败消息>失败，CreateOrderFailMessage: [{}]", message);
                    // TODO -lhl 记录录单失败的订单数据
                    return;
                }

                // timeWait分钟后，触发再次处理逻辑
                int timeWait = timeWaitUnit * procTimes;
                createOrderFailMessage.setProcessTimes(procTimes + 1);
                addRetryJob(createOrderFailMessage, timeWait);
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

    /**
     * 添加重试任务
     * @param createOrderFailMessage
     * @param timeWait 延迟时间，单位：分钟
     */
    private void addRetryJob(CreateOrderFailMessage createOrderFailMessage, int timeWait) {
        String msg = JSON.toJSONString(createOrderFailMessage);
        String msgId = DigestUtils.md5Hex(msg);
        Job job = new Job();
        job.setTaskId(TaskConsts.TASK_ID_ORDER_CREATE_FAIL + ":" + msgId);
        job.setParam(TaskManager.SHARD_FIELD, TaskConsts.TASK_ID_ORDER_CREATE_FAIL);
        job.setParam("createOrderFailMessage", msg);
        Date date = DateUtil.addMinute(DateUtil.getNow(), timeWait);
        taskManager.submitTask(job, -1, DateUtil.dateFormatToString(date, DateUtil.FORMAT_DEFAULT));
    }

    @Value("${oms.order-create-fail.retry.time-wait-unit:5}")
    public void setTimeWaitUnit(int timeWaitUnit) {
        this.timeWaitUnit = timeWaitUnit;
    }
}
